#ifndef THINK_THINK_PROCESS_PIPES_WINDOWS_H
#define THINK_THINK_PROCESS_PIPES_WINDOWS_H

static char* think_process_pipes_windows =
	"\n"
	"// +----------------------------------------------------------------------\n"
	"// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n"
	"// +----------------------------------------------------------------------\n"
	"// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n"
	"// +----------------------------------------------------------------------\n"
	"// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n"
	"// +----------------------------------------------------------------------\n"
	"// | Author: yunwuxin <448901948@qq.com>\n"
	"// +----------------------------------------------------------------------\n"
	"\n"
	"namespace think\\process\\pipes;\n"
	"\n"
	"use think\\Process;\n"
	"\n"
	"class Windows extends Pipes\n"
	"{\n"
	"\n"
	"    /** @var array */\n"
	"    private $files = [];\n"
	"    /** @var array */\n"
	"    private $fileHandles = [];\n"
	"    /** @var array */\n"
	"    private $readBytes = [\n"
	"        Process::STDOUT => 0,\n"
	"        Process::STDERR => 0,\n"
	"    ];\n"
	"    /** @var bool */\n"
	"    private $disableOutput;\n"
	"\n"
	"    public function __construct($disableOutput, $input)\n"
	"    {\n"
	"        $this->disableOutput = (bool) $disableOutput;\n"
	"\n"
	"        if (!$this->disableOutput) {\n"
	"\n"
	"            $this->files = [\n"
	"                Process::STDOUT => tempnam(sys_get_temp_dir(), \'sf_proc_stdout\'),\n"
	"                Process::STDERR => tempnam(sys_get_temp_dir(), \'sf_proc_stderr\'),\n"
	"            ];\n"
	"            foreach ($this->files as $offset => $file) {\n"
	"                $this->fileHandles[$offset] = fopen($this->files[$offset], \'rb\');\n"
	"                if (false === $this->fileHandles[$offset]) {\n"
	"                    throw new \\RuntimeException(\'A temporary file could not be opened to write the process output to, verify that your TEMP environment variable is writable\');\n"
	"                }\n"
	"            }\n"
	"        }\n"
	"\n"
	"        if (is_resource($input)) {\n"
	"            $this->input = $input;\n"
	"        } else {\n"
	"            $this->inputBuffer = $input;\n"
	"        }\n"
	"    }\n"
	"\n"
	"    public function __destruct()\n"
	"    {\n"
	"        $this->close();\n"
	"        $this->removeFiles();\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * {@inheritdoc}\n"
	"     */\n"
	"    public function getDescriptors()\n"
	"    {\n"
	"        if ($this->disableOutput) {\n"
	"            $nullstream = fopen(\'NUL\', \'c\');\n"
	"\n"
	"            return [\n"
	"                [\'pipe\', \'r\'],\n"
	"                $nullstream,\n"
	"                $nullstream,\n"
	"            ];\n"
	"        }\n"
	"\n"
	"        return [\n"
	"            [\'pipe\', \'r\'],\n"
	"            [\'file\', \'NUL\', \'w\'],\n"
	"            [\'file\', \'NUL\', \'w\'],\n"
	"        ];\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * {@inheritdoc}\n"
	"     */\n"
	"    public function getFiles()\n"
	"    {\n"
	"        return $this->files;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * {@inheritdoc}\n"
	"     */\n"
	"    public function readAndWrite($blocking, $close = false)\n"
	"    {\n"
	"        $this->write($blocking, $close);\n"
	"\n"
	"        $read = [];\n"
	"        $fh   = $this->fileHandles;\n"
	"        foreach ($fh as $type => $fileHandle) {\n"
	"            if (0 !== fseek($fileHandle, $this->readBytes[$type])) {\n"
	"                continue;\n"
	"            }\n"
	"            $data     = \'\';\n"
	"            $dataread = null;\n"
	"            while (!feof($fileHandle)) {\n"
	"                if (false !== $dataread = fread($fileHandle, self::CHUNK_SIZE)) {\n"
	"                    $data .= $dataread;\n"
	"                }\n"
	"            }\n"
	"            if (0 < $length = strlen($data)) {\n"
	"                $this->readBytes[$type] += $length;\n"
	"                $read[$type] = $data;\n"
	"            }\n"
	"\n"
	"            if (false === $dataread || (true === $close && feof($fileHandle) && \'\' === $data)) {\n"
	"                fclose($this->fileHandles[$type]);\n"
	"                unset($this->fileHandles[$type]);\n"
	"            }\n"
	"        }\n"
	"\n"
	"        return $read;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * {@inheritdoc}\n"
	"     */\n"
	"    public function areOpen()\n"
	"    {\n"
	"        return (bool) $this->pipes && (bool) $this->fileHandles;\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * {@inheritdoc}\n"
	"     */\n"
	"    public function close()\n"
	"    {\n"
	"        parent::close();\n"
	"        foreach ($this->fileHandles as $handle) {\n"
	"            fclose($handle);\n"
	"        }\n"
	"        $this->fileHandles = [];\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 创建一个新的 WindowsPipes 实例。\n"
	"     * @param Process $process\n"
	"     * @param         $input\n"
	"     * @return self\n"
	"     */\n"
	"    public static function create(Process $process, $input)\n"
	"    {\n"
	"        return new static($process->isOutputDisabled(), $input);\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 删除临时文件\n"
	"     */\n"
	"    private function removeFiles()\n"
	"    {\n"
	"        foreach ($this->files as $filename) {\n"
	"            if (file_exists($filename)) {\n"
	"                @unlink($filename);\n"
	"            }\n"
	"        }\n"
	"        $this->files = [];\n"
	"    }\n"
	"\n"
	"    /**\n"
	"     * 写入到 stdin 输入\n"
	"     * @param bool $blocking\n"
	"     * @param bool $close\n"
	"     */\n"
	"    private function write($blocking, $close)\n"
	"    {\n"
	"        if (empty($this->pipes)) {\n"
	"            return;\n"
	"        }\n"
	"\n"
	"        $this->unblock();\n"
	"\n"
	"        $r = null !== $this->input ? [\'input\' => $this->input] : null;\n"
	"        $w = isset($this->pipes[0]) ? [$this->pipes[0]] : null;\n"
	"        $e = null;\n"
	"\n"
	"        if (false === $n = @stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) {\n"
	"            if (!$this->hasSystemCallBeenInterrupted()) {\n"
	"                $this->pipes = [];\n"
	"            }\n"
	"\n"
	"            return;\n"
	"        }\n"
	"\n"
	"        if (0 === $n) {\n"
	"            return;\n"
	"        }\n"
	"\n"
	"        if (null !== $w && 0 < count($r)) {\n"
	"            $data = \'\';\n"
	"            while ($dataread = fread($r[\'input\'], self::CHUNK_SIZE)) {\n"
	"                $data .= $dataread;\n"
	"            }\n"
	"\n"
	"            $this->inputBuffer .= $data;\n"
	"\n"
	"            if (false === $data || (true === $close && feof($r[\'input\']) && \'\' === $data)) {\n"
	"                $this->input = null;\n"
	"            }\n"
	"        }\n"
	"\n"
	"        if (null !== $w && 0 < count($w)) {\n"
	"            while (strlen($this->inputBuffer)) {\n"
	"                $written = fwrite($w[0], $this->inputBuffer, 2 << 18);\n"
	"                if ($written > 0) {\n"
	"                    $this->inputBuffer = (string) substr($this->inputBuffer, $written);\n"
	"                } else {\n"
	"                    break;\n"
	"                }\n"
	"            }\n"
	"        }\n"
	"\n"
	"        if (\'\' === $this->inputBuffer && null === $this->input && isset($this->pipes[0])) {\n"
	"            fclose($this->pipes[0]);\n"
	"            unset($this->pipes[0]);\n"
	"        }\n"
	"    }\n"
	"}\n"
	"\n"
;
#endif